package org.example.java.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.javafx.collections.MappingChange;
import org.example.java.exception.NotFoundException;
import org.example.java.exception.StandardException;
import org.example.java.mapper.UserProfileMapper;
import org.example.java.model.User;
import org.example.java.model.UserProfile;
import org.example.java.request.UserCreateRequest;
import org.example.java.request.UserUpdateRequest;
import org.example.java.service.IUserProfileService;
import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

@Service
@Transactional
public class UserProfileServiceImpl extends ServiceImpl<UserProfileMapper, UserProfile> implements IUserProfileService {
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private UserProfileMapper userProfileMapper;
    @Override
    public UserProfile getByName(String name) {
        return userProfileMapper.selectOne(new QueryWrapper<UserProfile>().eq("name", name));
    }
    @Override
    public Integer getCountByName(String name) {
        return userProfileMapper.selectCount(new QueryWrapper<UserProfile>().eq("name", name));
    }
    @Override
    public Integer getCountByEmail(String email) {
        return userProfileMapper.selectCount(new QueryWrapper<UserProfile>().eq("email", email));
    }
    @Override
    public UserProfile getProfileCountByEmail(String email) {
        return userProfileMapper.selectOne(new QueryWrapper<UserProfile>().eq("email", email));
    }
    @Override
    public Map<String, Object> createUserProfile(UserCreateRequest userCreateRequest) {
        Integer existNameUsers = this.getCountByName(userCreateRequest.getName());
        Integer existEmailUsers = this.getCountByEmail(userCreateRequest.getEmail());
        if (existNameUsers > 0) {
            throw new StandardException("500", "name has already been used");
        }
        if (existEmailUsers > 0) {
            throw new StandardException("500", "email has already been used");
        }
        User user = new User();
        user.setStatus("normal");
        boolean isUserCreated = userService.createUser(user);
        if (isUserCreated) {
            UserProfile userProfile = new UserProfile();
            userProfile.setName(userCreateRequest.getName());
            userProfile.setEmail(userCreateRequest.getEmail());
            userProfile.setDob(userCreateRequest.getDob());
            userProfile.setUserId(user.getId());
            if (this.save(userProfile)) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("user", user);
                map.put("userProfile",userProfile);
                return map;
            }
            return null;
        }
        return null;
    }

    @Override
    public Map<String, Object> updateUserProfile(Long userId, UserUpdateRequest userUpdateRequest) {
        User user = userService.getById(userId);
        UserProfile userProfile = this.getByUserId(userId);
        if (user == null || userProfile ==  null) {
            throw new NotFoundException("user not found");
        }
        UserProfile userProfile2 = this.getProfileCountByEmail(userUpdateRequest.getEmail());
        if (userProfile2 != null && userProfile2.getUserId() != userId) {
            throw new IllegalArgumentException("email has already existed");
        }
        user.setId(userId);
        user.setStatus(userUpdateRequest.getStatus());
        boolean isUpdatedUser = userService.updateUser(user);
        if (isUpdatedUser) {
            userProfile.setName(userUpdateRequest.getName());
            userProfile.setEmail(userUpdateRequest.getEmail());
            userProfile.setDob(userUpdateRequest.getDob());
            boolean isUpdatedUserProfile = this.updateById(userProfile);
            if (isUpdatedUserProfile) {
                User user1 = userService.getById(userId);
                UserProfile userProfile1 = this.getByUserId(userId);
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("user", user1);
                map.put("userProfile", userProfile1);
                return map;
            }
            return null;
        }
        return null;
    }

    @Override
    public UserProfile getByUserId(Long userId) {
        return userProfileMapper.selectOne(new QueryWrapper<UserProfile>().eq("user_id", userId));
    }

    @Override
    public boolean removeByUserId(Long userId) {
        UserProfile userProfile = this.getByUserId(userId);
        if (userService.getById(userId) == null) {
            throw new NotFoundException("user not found");
        } else {
            userService.removeById(userId);
        }
        if (userProfile == null) {
            throw new NotFoundException("user not found");
        } else {
            this.removeById(userProfile.getId());
        }
        return true;
    }
}
